{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 表和元组之间的区别是什么？"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**相同点**  \n",
    "它们在 Python 中都是序列类型的容器对象，\n",
    "可以支持任何类型的数据存放、也同样支持切片和迭代等操作。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1, 2]\n",
      "(1, 2)\n"
     ]
    }
   ],
   "source": [
    "list1 = [1,2,3,4,5]\n",
    "print(list1[0:2])\n",
    "tuple1 = (1,2,3,4,5)\n",
    "print(tuple1[0:2])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**不同点**  \n",
    "1)列表是可变的，长度大小不固定，可以进行增删改等一系列操作。\n",
    "而元组是不可变的。大小固定，不可以进行增删改操作。\n",
    "你可以试着将一个元组重新赋值之后使用 id () 函数分别查看下新的元组和旧的元组在内存中的地址就知道了。  \n",
    "2)因为元组的不可变性，所以元组无法复制  \n",
    "3)可以使用元组作为字典的键，但是列表不可以。  \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{(1, 2): '元组'}\n"
     ]
    }
   ],
   "source": [
    "a = (1,2)\n",
    "b = [1,2]\n",
    "c = {a:'元组'} # 正确\n",
    "print (c)\n",
    "#c = {b:'列表'} # 错误\n",
    "#print (b)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "包)在两者的性能方面，Python 会将低开销的较大的块分配给元组，因为它们是不可变的。 \n",
    "对于列表则分配小内存块。 与列表相比，元组所支持的操作更少所以会更快一些。\n",
    "但其实这一点并没必要去过分纠结，除非你有超巨量的数据需要去处理。\n",
    "***存储相同的元素时，列表的大小比元组要大。这是因为列表是动态的，它需要存储指针来指向对应的元素***"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "64\n",
      "48\n"
     ]
    }
   ],
   "source": [
    "a = [1,2,3]\n",
    "b = (1,2,3)\n",
    "print(a.__sizeof__()) # 64\n",
    "print(b.__sizeof__()) # 48"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "***为什么有了列表，还需要有元组？***"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "之所以会有两种不同的数据结构是因为我们在使用的时候我们一般使用 List 来存储**同类型数据元素**，使用元组来存储**异构数据**。  \n",
    "比如用元组来记录一个人的身高，体重，年龄 person = (\"zhangsan\",18,180)。我们可以使用元组来存储棋盘上的某一个点，  \n",
    "但存储棋盘上的所有的点的时候你就应该使用列表了。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "point = (1,2) # 棋盘上的某一个点\n",
    "points = [(1,2),(3,4),(5,6)] # 存储棋盘上所有的点\n",
    "#Tips：也可以使用元组存储经纬度信息。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "列表占用的空间更大，性能低但是存储内容可变，元组占用空间更小，性能更高，但是存储内容不可变。\n",
    "两种数据结构的应用场景也不一样，所以才会有了两种不同的数据结构。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 拓展"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "说起了列表和元组，就不得不给大家说一下**序列（sequence）和容器（container）**了，序列（sequence）是一种数据结构，每个元素都分配了一个索引 ，从 0 开始，典型的序列就有列表，元组和字符串。其中列表可变，元组和字符串不可变。容器（container）包含其他对象的任何对象。序列和映射（mapping）是两种主要的容器。映射中的每个元素都分配了一个键，而字典是 python 中唯一内建的映射内型。键可以是数字，字符串或元组。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 加分点"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "在向面试官补充回答这道题的时候我们也可以说一下自身的在使用列表和元组时的经验，这样会更加的加分哦。\n",
    "\n",
    "以下为面试人口吻：我在平时使用列表这种数据结构的时候还发现了一个比较有意思的情况，Python 中有两种定义列表的方式：  \n",
    "\n",
    "list1 = list()  \n",
    "list1 = []  \n",
    "我分别打印了这两种方式创建列表的时间发现第二种方法的创建速度明显快于第一种方法，这是因为 list() 方法实际上是一个 Python 函数。而函数的调用一般会涉及一些堆栈调用的问题。而第二种方法则是由 Python 解释器直接实现的一个 C 函数，因此在性能上第二种方法会远优于第一种方法。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}